package com.winchain.chainbill.bill.biz.send.rx;

import com.shell.bee.persistence.transaction.Transaction;
import com.shell.bee.persistence.transaction.TransactionUtil;
import com.shell.framework.command.ChainBase;
import com.shell.framework.command.CommandContext;
import com.shell.framework.rx.OnErrorNotImplementedSubscriber;
import com.winchain.chainbill.bill.base.po.CbSnd;
import com.winchain.chainbill.bill.biz.Bill;
import com.winchain.chainbill.bill.biz.contract.cmd.ContractCancelCmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillMoveCmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillOptCmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillQuotaCmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillSndCmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillSndInvoinceRejectICmd;
import com.winchain.chainbill.bill.biz.send.cmd.BillSndMsgCmd;
import com.winchain.chainbill.bill.biz.send.vo.BatchBillStats;
import com.winchain.chainbill.bill.biz.send.vo.BillSnd;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class BillSndRevRjctSubscriber extends OnErrorNotImplementedSubscriber<BatchBillEvent<BillSnd, CbSnd>> {
	private final Log logger = LogFactory.getLog(getClass());
	@Autowired
	private BillOptCmd<CbSnd> billOptCmd;
	@Autowired
	private BillSndCmd billSndCmd;
	@Autowired
	private BillSndMsgCmd billSndMsgCmd;
	@Autowired
	private BillMoveCmd<CbSnd> billMoveCmd;
	@Autowired
	private BillQuotaCmd billQuotaCmd;
	@Autowired
	private ContractCancelCmd<CbSnd> contractCancelCmd;
	@Autowired
	private BillSndInvoinceRejectICmd<CbSnd> billSndInvoinceRejectICmd;

	public void onApplicationEvent(final BatchBillEvent<BillSnd, CbSnd> t) {
		List<BillSnd> records = t.getRecs();
		BatchBillStats<CbSnd> stats = t.getStats();
		final Bill<CbSnd> bill = new Bill();
		for (final BillSnd record : records) {
			try {
				TransactionUtil.execute(new Transaction() {
					public void doInTransaction() {
						bill.setRec(record.getRec());
						bill.setSource(record.getSnd());
						CommandContext<Bill<CbSnd>> context = new CommandContext();
						context.setSource(bill);
						context.setValue("Operation", t.getOperation());
						context.setValue("TimeoutOperation", t.getTimeoutOpt());

						context.setValue("bizType", "SND_REJECT");

						ChainBase<Bill<CbSnd>> crb = new ChainBase();
						crb.add(BillSndRevRjctSubscriber.this.billOptCmd);
						crb.add(BillSndRevRjctSubscriber.this.billSndCmd);
						crb.add(BillSndRevRjctSubscriber.this.billMoveCmd);
						crb.add(BillSndRevRjctSubscriber.this.billSndMsgCmd);
						crb.add(BillSndRevRjctSubscriber.this.billQuotaCmd);
						crb.add(BillSndRevRjctSubscriber.this.contractCancelCmd);
						crb.add(BillSndRevRjctSubscriber.this.billSndInvoinceRejectICmd);
						crb.execute(context);

						t.setValue("txSn", context.getValue("txSn"));
					}
				}, new int[0]);

				stats.addPassedRecord(bill);
			} catch (Exception e) {
				e.printStackTrace();
				this.logger.error("ArRecord Impt Rev pass error!", e);
				stats.addAbnormalRecord(bill);
				stats.addAbnormalMsg(e.getMessage());
			}
		}
	}
}
